package org.xsoft.myminidao.factory;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Set;

import org.apache.log4j.Logger;
import org.xsoft.myminidao.annotation.MiniDao;
import org.xsoft.myminidao.aop.MiniDaoHandler;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;

/**
 * 扫描daoInterface
 * 组建动态代理工厂MiniDaoBeanFactory
 *
 */
public class MiniDaoClassPathMapperScanner extends ClassPathBeanDefinitionScanner {

    private static final Logger logger = Logger.getLogger(MiniDaoHandler.class);

    //指定Scanner扫描的注解
    //默认@MiniDao 也可以是@Repository
    public MiniDaoClassPathMapperScanner(BeanDefinitionRegistry registry, Class<? extends Annotation> annotation) {
        super(registry, false);
        addIncludeFilter(new AnnotationTypeFilter(annotation));
        if (!MiniDao.class.equals(annotation)) {
            addIncludeFilter(new AnnotationTypeFilter(MiniDao.class));
        }
    }

    //将扫描到的daoInterface，与之前注册的miniDaoHandler，组建动态代理工厂MiniDaoBeanFactory
    @Override
    public Set<BeanDefinitionHolder> doScan(String... basePackages) {
    	//扫描到的daoInterface
        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

        if (beanDefinitions.isEmpty()) {
            logger.warn("No Dao interface was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
        }
        
        GenericBeanDefinition definition;
        for (BeanDefinitionHolder holder : beanDefinitions) {
            definition = (GenericBeanDefinition) holder.getBeanDefinition();
            definition.getPropertyValues().add("proxy", getRegistry().getBeanDefinition("miniDaoHandler"));//Invocation Handler
            definition.getPropertyValues().add("daoInterface", definition.getBeanClassName()); //target
            if (logger.isInfoEnabled()) {
                logger.info("register minidao name is { " + definition.getBeanClassName() + " }");
            }
            definition.setBeanClass(MiniDaoBeanFactory.class);//动态代理工厂
        }

        return beanDefinitions;
    }

    /**
     * 默认不允许接口的,这里重写,覆盖下,另外默认会Scan @Component 这样所以的被@Component 注解的都会Scan
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
    }

}
